﻿using System;
using System.IO;
using System.Configuration;
using System.Windows.Forms;
using System.Threading;

using DreamCube.WebServer.WinServiceModel;
using DreamCube.WinForm.Common;
using DreamCube.Foundation.Basic.Utility;
using DreamCube.Foundation.Basic.Objects;
using DreamCube.Foundation.Serialization;
using DreamCube.Framework.Utilities.BasicObject;

namespace DreamCube.WebServer.WebHost.UI
{
    public partial class MainForm : Form
    {
        private Boolean isRunning = false;
        private Server webServer = null;
        /// <summary>
        /// 自动启动IIS服务，默认是true的
        /// </summary>
        private Boolean autoRunIISService = true;


        public MainForm()
            : this(null)
        { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="args">命令行参数</param>
        public MainForm(String[] args)
        {
            this.autoRunIISService = (args != null && args.Length > 0) ? (args[0].ToLower() == "true") : this.autoRunIISService;
            InitializeComponent();
            InitialData();
        }

        /// <summary>
        /// 初始化数据
        /// </summary>
        private void InitialData()
        {
            try
            {
                ServerConfig config = ObjectXHelper.CreateObjFromJSONRegistry_LocalMachine<ServerConfig>(Common.ConfigDataRegistryKey, Common.ConfigDataPropertyName);
                if (config != null)
                {
                    txt_port.Text = config.Port.ToString();
                    txt_PhysicalPath.Text = config.WebPhysicalPath;
                    txt_DefaultDoc.Text = config.DefaultDos == null ? "" : MyEnumerable.JoinEx(config.DefaultDos, ";");
                    lb_serverState.Text = "停止";
                }
                else
                {
                    txt_port.Text = ConfigurationManager.AppSettings["WebPort"];
                    txt_PhysicalPath.Text = ConfigurationManager.AppSettings["WebPath"];
                    txt_DefaultDoc.Text = ConfigurationManager.AppSettings["DefaultDocs"];
                    lb_serverState.Text = "停止";
                }
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 保存配置参数的按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            DoStartServer();
        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        private void StopServer()
        {
            try
            {
                if (webServer != null) webServer.Stop();
                webServer = null;
                isRunning = false;
                lb_serverState.Text = "停止";
                btn_StartServer.Text = "启动服务器";
                DeleteDll();
                DisableInput(true);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 确保删除了dll，否则影响IIS的部署
        /// </summary>
        private void DeleteDll()
        {
            String path = Path.Combine(txt_PhysicalPath.Text, "bin");
            String fileName = ConfigurationManager.AppSettings["HostDllFileName"];
            if (String.IsNullOrEmpty(fileName)) fileName = "DreamCube.WebServer.WebHost.dll";
            String dllFile = Path.Combine(path, fileName);
            String pdbFile = Path.Combine(path, MyString.LeftOfLast(fileName, ".", false, "") + ".pdb");
            if (File.Exists(dllFile))
            {
                MyIO.FileDelete(dllFile);
            }
            if (File.Exists(pdbFile))
            {
                MyIO.FileDelete(pdbFile);
            }
        }

        /// <summary>
        /// 执行启动服务器
        /// </summary>
        /// <param name="restart">标志是否是重启操作</param>
        private void DoStartServer(Boolean restart = false)
        {
            if (!ValidateData()) return;
            if (!restart && isRunning)
            {
                StopServer();
            }
            else
            {
                try
                {
                    //退出原来的那个服务器
                    if (webServer != null)
                        webServer.Stop();
                }
                catch (Exception)
                { }
                try
                {
                    Int32 port = 80;
                    Int32.TryParse(txt_port.Text, out port);
                    //默认文档
                    String defaultDoc = ConfigurationManager.AppSettings["DefaultDocs"];
                    if (!String.IsNullOrEmpty(txt_DefaultDoc.Text))
                        defaultDoc = txt_DefaultDoc.Text;

                    CopyDll(); //先复制依赖的dll
                    webServer = new Server(port, "/", txt_PhysicalPath.Text, false, false, defaultDoc.Split(';'));
                    webServer.Start();
                    isRunning = true;
                    DisableInput();
                    MyControl.ControlInvoke(this, new Action(delegate
                    {
                        lb_serverState.Text = "运行ing";
                        btn_StartServer.Text = "停止服务器";
                    }));
                    //ThreadPool.QueueUserWorkItem(new WaitCallback((oIn) =>
                    //{
                    //    StartCheckServiceState();
                    //}), null);
                }
                catch (Exception ex)
                {
                    MyLog.MakeLog(ex);
                    lb_serverState.Text = "启动服务器发生异常，请联系South！";
                }
            }
        }

        /// <summary>
        /// 禁止输入
        /// </summary>
        private void DisableInput(Boolean enable = false)
        {
            MyControl.ControlInvoke(this, new Action(delegate
            {
                txt_hostDllFilePath.Enabled = enable;
                txt_port.Enabled = enable;
                txt_PhysicalPath.Enabled = enable;
                txt_DefaultDoc.Enabled = enable;
                btn_SaveConfig.Enabled = enable;
                ck_autoRun.Enabled = enable;
            }));
        }

        /// <summary>
        /// 复制依赖的dll和调试的pdb
        /// </summary>
        private void CopyDll()
        {
            String path = AppDomain.CurrentDomain.BaseDirectory;
            String fileName = ConfigurationManager.AppSettings["HostDllFileName"];
            if (String.IsNullOrEmpty(fileName)) fileName = "DreamCube.WebServer.WebHost.dll";
            String dllFile = Path.Combine(path, fileName);
            String pdbFile = Path.Combine(path, MyString.LeftOfLast(fileName, ".", false, "") + ".pdb");
            if (File.Exists(dllFile))
            {
                MyIO.FileCopy(dllFile, Path.Combine(txt_PhysicalPath.Text, "bin"), true, "");
            }
            else
            {
                throw new Exception("承载服务器的dll找不到，联系管理员");
            }
            if (File.Exists(pdbFile))
            {
                MyIO.FileCopy(pdbFile, Path.Combine(txt_PhysicalPath.Text, "bin"), true, "");
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //取消关闭逻辑
            e.Cancel = true;
            this.Hide();
        }

        /// <summary>
        /// 窗体显示之后触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Shown(object sender, EventArgs e)
        {
            try
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback((oIn) =>
                {
                    ConfigForm();
                    //如果配置了自动启动服务，则窗体显示之后马上启动服务
                    if (this.autoRunIISService && ValidateData())
                        DoStartServer();
                }), null);
            }
            catch (Exception ex)
            {
                MyLog.MakeLog(ex);
            }
        }

        /// <summary>
        /// 定时器
        /// </summary>
        private System.Threading.Timer timer = null;
        /// <summary>
        /// 开始检查服务的状态
        /// </summary>
        private void StartCheckServiceState()
        {
            if (timer == null)
            {
                timer = new System.Threading.Timer(new TimerCallback((o) =>
                {
                    try
                    {
                        if (isRunning) DoCheckServiceState();
                    }
                    catch (Exception)
                    { }
                    finally
                    {
                        timer.Change(5000, Timeout.Infinite);
                    }
                }), null, 5000, Timeout.Infinite);
            }
        }

        /// <summary>
        /// 检查服务的状态
        /// </summary>
        private void DoCheckServiceState()
        {
            String result = MyWeb.PostTo(Common.WebLivePagePath, "");
            MyControl.ControlInvoke(this, new Action(() =>
            {
                if (result != "true") //服务器崩溃了
                {
                    lb_serverState.Text = "服务器已停止！";
                    isRunning = false;
                    //重启服务器
                    DoStartServer(true);
                }
                else
                {
                    lb_serverState.Text = "运行ing！";
                }
            }));
        }

        private void MainForm_MaximumSizeChanged(object sender, EventArgs e)
        {
            
        }

        private void MainForm_ClientSizeChanged(object sender, EventArgs e)
        {
            //最小化处理
            if (this.WindowState == FormWindowState.Minimized)
            {
                //this.Hide();
                //不在任务栏显示窗体
                //this.ShowInTaskbar = false;
            }
        }

        private void 退出程序ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBoxEx.Show(this,"你确定要退出打印服务器吗？", "确认", MessageBoxButtons.OKCancel,
                 MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                //停止服务器
                StopServer();
                notifyIcon1.Visible = false;
                this.Close();
                this.Dispose();
                Application.Exit();
            }       
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            //双击显示
            if (e.Button == MouseButtons.Left)
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
                this.Activate();
            }
        }

        /// <summary>
        /// 验证数据是否合法的
        /// </summary>
        /// <returns></returns>
        protected Boolean ValidateData()
        {
            Int32 port = 80;
            if (!(Int32.TryParse(txt_port.Text, out port) && port >= 1 && port <= 60000))
            {
                MessageBoxEx.Show("端口号必须为1-60000！", "提醒");
                return false;
            }
            if (String.IsNullOrEmpty(txt_PhysicalPath.Text) || !Directory.Exists(txt_PhysicalPath.Text))
            {
                MessageBoxEx.Show("指定的网站目录不存在！", "提醒");
                return false;
            }
            if (String.IsNullOrEmpty(txt_hostDllFilePath.Text) || !File.Exists(txt_hostDllFilePath.Text))
            {
                MessageBoxEx.Show("指定的承载Dll文件不存在！", "提醒");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 执行保存配置的方法
        /// </summary>
        private void DoSaveConfig()
        {
            //ObjectX obj = ObjectXHelperEx.CreateObjFromForm(this);
            if (ValidateData())
            {
                ServerConfig config = new ServerConfig
                {
                    DefaultDos = MyString.SplitEx(txt_DefaultDoc.Text, ";", StringSplitOptions.RemoveEmptyEntries),
                    WebVirtualPath = "/",
                    Port = MyString.ToInt32(txt_port.Text),
                    WebPhysicalPath = txt_PhysicalPath.Text,
                    AutoRun = ck_autoRun.Checked,
                    HostDllFilePath = txt_hostDllFilePath.Text
                };
                //把配置数据保存到注册表中
                config.SaveJSONToRegistry_LocalMachine(Common.ConfigDataRegistryKey, Common.ConfigDataPropertyName);
                MessageBoxEx.Show("保存成功！", "提醒");

                //保存成功后就启动服务器
                //DoStartServer();
            }
        }

        /// <summary>
        /// 配置窗体数据
        /// </summary>
        private void ConfigForm()
        {
            ObjectX obj = ObjectXHelper.CreateObjFromJSONRegistry_LocalMachine(Common.ConfigDataRegistryKey, Common.ConfigDataPropertyName);
            MyControl.ControlInvoke(this, new Action(() =>
            {
                ObjectXHelperEx.WriteObjToForm(obj, this);
            }));
        }

        /// <summary>
        /// 改变开机自启动的选择时触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ck_autoRun_CheckedChanged(object sender, EventArgs e)
        {
            //String appPath = MyPath.ExecutablePath;
            MyRegistry.Example.ConfigAutoStartApp("South PrintServer", ck_autoRun.Checked);
        }

        /// <summary>
        /// 保存配置数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_SaveConfig_Click(object sender, EventArgs e)
        {
            DoSaveConfig();
        }
    }
}
